package com.guiwu.gteway.industryapp.Device.module;

import com.guiwu.gteway.industryapp.Api.GuiwuApi;
import com.guiwu.gteway.industryapp.Api.GuiwuApiCallback;
import com.guiwu.gteway.industryapp.Frame.FrameHelper;
import com.guiwu.gteway.industryapp.util.MyLog;

import java.io.IOException;
import java.util.Date;

/**
 * Created by qiaoguan on 2018/3/24. 监控点基本类
 */

public abstract class Monitor {

    private static final String TAG = "Monitor";

    public static final int BIT = 0x01;
    public static final int BIT16 = 0x02;
    public static final int BIT32 = 0x03;

    public static final int COIL = 0x04;
    public static final int REGISTER = 0x05;

    String dataType;
    boolean dataAbnormal;
    String name;
    String writeRead;
    int value;
    String lastTime;
    Date date;
    int addressAdd;
    String addressType;
    String dataString;
    String streamID;
    int [] decimal = new int[2];
    int slaveAdr;
    String protocol;
    int max;
    int repeatTime;
   // boolean switchCanControl;
    int modBusAdd;
    String modBusRegType;
    String bindDeviceType;
    String nickName;
    boolean authority;
    String unit;

    public Monitor(MonitorData monitorData){
        this.name = monitorData.getStreamName();
        this.dataType = monitorData.getDataType();
        this.writeRead = monitorData.getWriteRead();
        this.lastTime = monitorData.getLastTime();
        this.streamID = monitorData.getStreamId();
        this.addressAdd = monitorData.getAddress();
        this.addressType = monitorData.getAddressType();
        decimal[0] = monitorData.getIntBit();
        decimal[1] = monitorData.getDecimalBit();
        slaveAdr = monitorData.getSlaveAdr();
        protocol = monitorData.getCmd().getProtocol();
        modBusAdd = monitorData.getModbusRegisterAdd();
        modBusRegType = monitorData.getModbusCode();
        bindDeviceType = monitorData.getBindDeviceType();
        nickName = monitorData.getBindDeviceNickName();
        unit = monitorData.getUnit();
        initMax();
    }

    private void initMax(){
        if (getMonitorType() == BIT16)
            max = 65535;
        else if (getMonitorType() == BIT32)
            max = Integer.MAX_VALUE;
    }

    public abstract int getMonitorType();

    public boolean isWriteable(){
        return writeRead.equalsIgnoreCase("wr");
    }

    //数据是否异常
    public boolean isDataAbnormal(){
        return dataAbnormal;
    }

    public void setAbnormal(Boolean isDataAbnormal){
        this.dataAbnormal  = isDataAbnormal;
    }

    public abstract  String getValue();
    public abstract String getTypeValue(int inputValue);

    public int getValueInt(){
        return value;
    }

    //给value加上小数点
    public static String addDeciaml(int value,int deci){
        if (deci == 0){
            return String.valueOf(value);
        }
        StringBuilder newValue = new StringBuilder(String.valueOf(value));
        if (newValue.length() <= deci){
            StringBuilder s = new StringBuilder("0.");
            for (int j = 0;j< deci - newValue.length() ;j++)
                s.append('0');
            return newValue.insert(0,s).toString();
        }

        newValue.insert(newValue.length() - deci,'.');
        return newValue.toString();
    }

    public void setValue(int value) {
     //   if (!handleResend())
//        if (value != this.value && MonitorListFragment.sTimes != 0) {//说明没有改变成功
//            if (repeatListener != null){
//                repeatListener.repeat();
//            }
//            if (MonitorListFragment.sTimes == 3)
//                MonitorListFragment.sTimes = 0;
//            return;
//        }else {
//            this.value = value;
//            MonitorListFragment.sTimes = 0;
//        }
            this.value = value;
    }

    public String getName(){
        return name;
    }

    public String getStreamID() {
        return streamID;
    }

    public void setStreamID(String streamID) {
        this.streamID = streamID;
    }

    public String getDataString() {
        return dataString;
    }

    public void setDataString(String dataString) {
        this.dataString = dataString;
    }

    public int[] getDecimal() {
        return decimal;
    }

    //获得镜像id号
    public String getMirrorId(){
        String mirrorId = null;
        if (streamID != null && streamID.length() == 4){
            int id = Integer.valueOf(streamID,16);
            int intMirrorId = id + 0x8000;
            if (intMirrorId > 0xffff)
                return null;
            mirrorId = Integer.toHexString(intMirrorId);
        }
        return mirrorId;
    }

    public abstract void sendCmd(String deviceId ,String apiKey,boolean coil);
    public abstract void sendCmd(String deviceId ,String apiKey,int value);
    public abstract String getCoilFrame(boolean coil);
    public abstract String getRegFrame(int value);


    //重发次数判断
    public int getRepeatTime() {
        return repeatTime;
    }
    public void resetRepeatTime(){
        this.repeatTime = 0;
    }
    public void repeat() {
        repeatTime++;
        if (repeatTime == 6)
            repeatTime = 0;
    }

    public String getBindDeviceType() {
        return bindDeviceType;
    }

    public int getModBusAdd() {
        return modBusAdd;
    }

    public String getAddressType() {
        return addressType;
    }

    public int getAddressAdd() {
        return addressAdd;
    }

    public String getNickName() {
        return nickName;
    }

    public String getDataType() {
        return dataType;
    }

    public boolean getSwitchState(){
        if (dataType.equalsIgnoreCase("bit")){
            if (value % 2 == 0)
                return false;
            else
                return true;
        }
        return false;
    }

    public int getMax(){
        return max;
    }

    @Override
    public String toString() {
        return this.name + ":" + this.dataType + "   " + this.writeRead + "  " + this.dataAbnormal + "   " + this.streamID + "   " + this.value;
    }

    public interface dateReturn {
        void success(String response);
        void fail(String error);
    }

    protected dateReturn listener;

    public void  setDataReturnListener(dateReturn listener){
        this.listener = listener;
    }

    protected void handleCmd(String deviceId ,String apiKey,String cmdFrame){
        try {
            String cmdString = FrameHelper.cmdForContorl(streamID,cmdFrame,protocol);
            MyLog.i(TAG,cmdString);
            GuiwuApi.controlMonitor(cmdString, deviceId, apiKey, new GuiwuApiCallback() {
                @Override
                public void onSuccess(String response) {
                    if (listener != null){
                        listener.success(response);
                    }
                }

                @Override
                public void onFailed(Exception e) {
                    if (listener != null){
                        listener.fail(e.getMessage());
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
